Previous topicNext topic
Help > Keyword Reference >
UNION/END UNION block

Remarks

A union is a type - very similar to a User-Defined Type - except that its elements overlap in memory. While this may seem strange at first, it has enormous potential.

For example, say you are designing an accounting program. You want to make it general purpose so it has widespread appeal. But everyone does their accounting differently; for example, some people use account numbers that are plain integral values, while others may use alphanumeric account names. Using a Union makes this easy. Another common use of a Union is variable type conversion. The is best described by way of an example:

UNION VarConvert

 iLong  AS LONG

 iDword AS DWORD

 sStr   AS STRING * 4

END UNION

 

DIM x AS VarConvert, y AS DWORD, z AS STRING

x.iLong = 123456&

y       = x.iDword

z       = x.sStr

Like a User-Defined Type, a Union may also contain arrays, and these follow the same rules as User-Defined Type member arrays (see Type Members for syntax rules and additional examples). The following example demonstrates the use of a Union member array:

UNION Arrs

 a1(1 TO 1024) AS BYTE

 st AS ASCIIZ * 10

END UNION

 

FUNCTION PBMAIN

   DIM a AS Arrs

   a.a1(1) = 72

   a.a1(2) = 101

   a.a1(3) = 108

   a.a1(4) = 108

   a.a1(5) = 111

   a.a1(6) = 33

   ' At this point, a.st contains "Hello!"

END FUNCTION

Bit Variables

UNION structures may contain bit variables, which are named BIT (unsigned values) or SBIT (signed values). Each bit variable may occupy from 1 to 31 bits, and they may be packed one after another up to a total of 32 bits per bit field. The size of a bit variable is defined as follows:

var AS BIT * nlit [IN BYTE|WORD|DWORD]

…where the term "* nlit" defines the number of bits (1 to 31), and the optional term "IN BYTE|WORD|DWORD", if present, defines the start of a new bit field of 1, 2, or 4 bytes. For example:

UNION ABCDE

 Odd1 AS BIT * 1 IN DWORD

 Value1 AS LONG

END UNION

The example UNION structure above is 4 bytes in size, containing a 1-byte bit field and a 4-byte LONG.

UNION abcde

 Part1 AS BIT * 8 IN DWORD

 Part2 AS BIT * 16

END UNION

The example union above is 4 bytes in size, containing an 8-bit field and an overlapping 16-bit field.

Structures within structures

Structures (TYPE/UNION) may be embedded within another structure, for simplification in referencing deeply nested items, by simply stating the structure name alone at the appropriate position. The internal alignment of the member structure is precisely maintained regardless of other alignment specifications, to foster inheritance issues. For example:

TYPE ABCD3  

A AS LONG  

ABCD2

C AS LONG  

END TYPE

TYPE ABCD2  

D AS DWORD  

E AS DOUBLE  

ABCD1        

END TYPE

UNION ABCD1

F AS DWORD

G AS LONG

H AS SINGLE

END UNION

In this case, you could access the lone Single-precision float member of this structure very simply. Assuming DIM X AS ABCD3, you could reference the Single-precision Union member with the variable name X.H, instead of the extended syntax X.ABCD2.ABCD1.H

Restrictions

A Union can contain elements of dissimilar sizes. The size of a Union structure is always determined by the longest member element. This is usually an important consideration when using a Union within another Union or UDT structure, in order to determine the size of the final structure.

For related information, please refer to the TYPE/END TYPE, User-Defined Types and Unions sections.

Field strings cannot be used in UDT or UNION structures. Attempting to do so results in a compile-time Error 485 ("Dynamic/Field strings not allowed").

See also

DIM, LEN, LET (with Types), SIZEOF, TYPE/END TYPE, User-Defined Types, Unions

Example

UNION AccountUnion

 AccountNumber  AS LONG

 AccountName    AS STRING * 16

END UNION

 

TYPE JournalEntryType

 Account  AS AccountUnion

 Amount   AS CUR

END TYPE

 

DIM JournalEntry AS JournalEntryType

 

JournalEntry.Account.AccountName = "Smith"

JournalEntry.Amount = 123.01@

' process journal entry here

JournalEntry.Account.AccountNumber = 1001

JournalEntry.Amount = -1.99@